
import sys
import threading
import queue
import cv2
import tkinter as tk
import sys
if sys.platform == "linux":
    try:
        from PIL import Image, ImageTk
        PIL_AVAILABLE = True
    except ImportError:
        PIL_AVAILABLE = False
        print("PIL未安装，linux将无法使用tkinter预览功能")

class VideoPreviewManager:
    """视频预览管理器，仅支持Linux下的tkinter预览"""
    
    def __init__(self):
        self.frame_queue = queue.Queue(maxsize=10)  # 限制队列大小避免内存溢出
        self.preview_thread = None
        self.running = False
        
        # 仅支持Linux下的tkinter预览
        if sys.platform == "linux" and PIL_AVAILABLE:
            self.preview_type = "tkinter"
            print("使用预览方式: tkinter")
            try:
                self._start_preview_thread()
                # 等待一小段时间检查线程是否正常启动
                import time
                time.sleep(0.1)
                if not self.running:
                    print("tkinter预览启动失败")
                    self.running = False
            except Exception as e:
                print(f"tkinter预览启动失败: {e}")
                self.running = False
        else:
            self.preview_type = "none"
            self.running = False
            if sys.platform == "linux":
                print("预览功能不可用")
            else:
                print("Windows将使用opencv预览")
    
    def _start_preview_thread(self):
        """启动预览线程"""
        self.running = True
        self.preview_thread = threading.Thread(target=self._tkinter_preview_loop, daemon=True)
        self.preview_thread.start()
    
    def update_frame(self, frame, window_name="Video"):
        """更新预览帧"""
        if not self.running or self.preview_type != "tkinter":
            return
            
        # 将帧放入队列供预览线程使用
        try:
            self.frame_queue.put_nowait((frame.copy(), window_name))
        except queue.Full:
            # 队列满了，丢弃旧帧
            try:
                self.frame_queue.get_nowait()
                self.frame_queue.put_nowait((frame.copy(), window_name))
            except queue.Empty:
                pass
    
    def _tkinter_preview_loop(self):
        """tkinter预览循环 - 为每个窗口创建独立窗口"""
        try:
            # 存储不同窗口的标签
            self.windows = {}
            self.labels = {}
            
            def create_window(window_name):
                """为指定窗口名创建新窗口"""
                if window_name not in self.windows:
                    # 创建新窗口
                    window = tk.Toplevel()
                    window.title(f"视频预览 - {window_name}")
                    window.geometry("640x480")
                    
                    # 创建标签用于显示图像
                    label = tk.Label(window)
                    label.pack(expand=True, fill='both')
                    
                    self.windows[window_name] = window
                    self.labels[window_name] = label
                    
                    # 窗口关闭时的处理
                    def on_closing():
                        if window_name in self.windows:
                            del self.windows[window_name]
                        if window_name in self.labels:
                            del self.labels[window_name]
                    
                    window.protocol("WM_DELETE_WINDOW", on_closing)
            
            def update_preview():
                try:
                    frame, window_name = self.frame_queue.get_nowait()
                    
                    # 确保窗口存在
                    if window_name not in self.windows:
                        create_window(window_name)
                    
                    # 检查窗口是否还存在
                    if window_name in self.windows and self.windows[window_name].winfo_exists():
                        # 转换BGR到RGB
                        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                        
                        # 调整图像大小
                        height, width = frame_rgb.shape[:2]
                        max_size = 480
                        if height > max_size or width > max_size:
                            scale = max_size / max(height, width)
                            new_width = int(width * scale)
                            new_height = int(height * scale)
                            frame_rgb = cv2.resize(frame_rgb, (new_width, new_height))
                        
                        # 转换为PIL图像
                        pil_image = Image.fromarray(frame_rgb)
                        tk_image = ImageTk.PhotoImage(pil_image)
                        
                        # 更新标签
                        self.labels[window_name].configure(image=tk_image)
                        self.labels[window_name].image = tk_image  # 保持引用
                    
                except queue.Empty:
                    pass
                except Exception as e:
                    print(f"tkinter预览错误: {e}")
                
                if self.running:
                    # 使用33ms间隔，约30fps
                    root.after(33, update_preview)
            
            # 创建主窗口（隐藏）
            root = tk.Tk()
            root.withdraw()  # 隐藏主窗口
            
            update_preview()
            root.mainloop()
            
        except Exception as e:
            print(f"tkinter预览初始化失败: {e}")
            self.running = False
    
    def stop(self):
        """停止预览"""
        self.running = False
        if self.preview_thread and self.preview_thread.is_alive():
            self.preview_thread.join(timeout=1.0)